//
// Created by 29245 on 2025/8/26.
//

#include "Servo.h"
#include "main.h"
#include "tim.h"
/**
 * @brief  初始化舵机PWM输出
 * @note   配置参数: 预分频器720, 自动重装载值2000
 * @param  None
 * @retval None
 */

void Servo_Init(void)
{
    // 启动TIM3定时器的PWM输出通道
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);

    // 可选：初始化舵机到中位(90度)
    //Servo_SetAngle(TIM_CHANNEL_3, 90);
   // Servo_SetAngle(TIM_CHANNEL_4, 90);
}

/**
 * @brief  设置舵机角度
 * @param  channel: 定时器通道 (TIM_CHANNEL_3 或 TIM_CHANNEL_4)
 * @param  angle: 目标角度 (0-180度)
 * @retval None
 */
void Servo_SetAngle(uint32_t channel, uint16_t angle)
{
    // 限制角度范围在0-180度之间
    if(angle > 180)
        angle = 180;

    // 根据当前配置计算脉冲宽度
    // 当前配置：每个计数周期0.01ms，PWM周期20ms(2000个计数)
    // SG90舵机脉冲宽度范围：0.5ms-2.5ms
    // 对应计数值范围：50-250 (0.5ms/0.01ms = 50, 2.5ms/0.01ms = 250)

    uint32_t pulse = 50 + (angle * (250 - 50)) / 180;

    // 设置比较值以控制舵机角度
    __HAL_TIM_SET_COMPARE(&htim3, channel, pulse);
}

/**
 * @brief  设置舵机脉冲宽度(直接控制脉冲宽度)
 * @param  channel: 定时器通道 (TIM_CHANNEL_3 或 TIM_CHANNEL_4)
 * @param  pulse_width_us: 脉冲宽度(微秒) (500-2500us)
 * @retval None
 */
void Servo_SetPulseWidth(uint32_t channel, uint16_t pulse_width_us)
{
    // 限制脉冲宽度在500-2500微秒之间
    if(pulse_width_us < 500)
        pulse_width_us = 500;
    if(pulse_width_us > 2500)
        pulse_width_us = 2500;

    // 将微秒转换为计数值
    // 当前配置：每个计数周期0.01ms = 10us
    uint32_t pulse = pulse_width_us / 10;

    // 设置比较值
    __HAL_TIM_SET_COMPARE(&htim3, channel, pulse);
}

/**
 * @brief  舵机扫动示例函数
 * @param  channel: 定时器通道
 * @retval None
 */
void Servo_Sweep(uint32_t channel)
{
    static uint16_t angle = 0;
    static int8_t direction = 1;

    Servo_SetAngle(channel, angle);

    angle += direction;
    if(angle >= 180)
    {
        angle = 180;
        direction = -1;
    }
    else if(angle <= 0)
    {
        angle = 0;
        direction = 1;
    }

    // 延时让舵机有时间转动
    HAL_Delay(20);
}
